package cn.itsource.zcn.user.service.impl;

import cn.itsource.zcn.user.domain.Logininfo;
import cn.itsource.zcn.user.domain.User;
import cn.itsource.zcn.user.domain.Wxuser;
import cn.itsource.zcn.user.mapper.LogininfoMapper;
import cn.itsource.zcn.user.mapper.UserMapper;
import cn.itsource.zcn.user.mapper.WxuserMapper;
import cn.itsource.zcn.user.service.IWxuserService;
import cn.itsource.zcn.utils.AjaxResult;
import cn.itsource.zcn.utils.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * (Wxuser)表服务实现类
 *
 * @author makejava
 * @since 2021-08-20 22:10:30
 */
@Service
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class WxuserServiceImpl implements IWxuserService {
    @Autowired
    private WxuserMapper tWxuserMapper;
    @Autowired
    private UserMapper tUserMapper;
    @Autowired
    private LogininfoMapper tLogininfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 新增数据
     *
     * @param tWxuser 实例对象
     */
    @Override
    @Transactional
    public void save(Wxuser tWxuser) {
        tWxuserMapper.save(tWxuser);
    }

    /**
     * 修改数据
     *
     * @param tWxuser 实例对象
     */
    @Override
    @Transactional
    public void update(Wxuser tWxuser) {
        tWxuserMapper.update(tWxuser);
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     */
    @Override
    @Transactional
    public void delete(Long id) {
        tWxuserMapper.delete(id);
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Wxuser queryById(Long id) {
        return tWxuserMapper.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @return 对象列表
     */
    @Override
    public List<Wxuser> queryAll() {
        return tWxuserMapper.queryAll();
    }

    // 微信扫码登录
    //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    /*
    {
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE",
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
    }
     */
    @Override
    @Transactional
    public AjaxResult login(Map<String, String> map) {
        String code = map.get("code");
        //发送请求去拿access_token
        String result = HttpUtil.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxd853562a0548a7d0&secret=4a5d5615f93f24bdba2ba8534642dbb6&code=" + code + "&grant_type=authorization_code");
        //把结果转换成java对象
        JSONObject jsonObject = JSON.parseObject(result);
        String openid = jsonObject.getString("openid");
        String access_token = jsonObject.getString("access_token");
        // 根据查询到的openid去数据库查询
        Wxuser wxuser = tWxuserMapper.queryByOpenid(openid);
        // 如果wxuser存在，说明他是老用户
        if(wxuser!=null){
            //就查询相关数据
            User user = tUserMapper.queryById(wxuser.getUser_id());
            Logininfo logininfo = tLogininfoMapper.queryByUid(user.getId());
            //免密登录
            return noPwdLogin(logininfo);
        }else{
            redisTemplate.opsForValue().set("openid",openid,15,TimeUnit.MINUTES);
            redisTemplate.opsForValue().set("access_token",access_token,15,TimeUnit.MINUTES);
            // 如果wxuser不存在，就是跳转到绑定电话页面
            return new AjaxResult().setResultObj("/bindwechart.html").setSuccess(false);
        }


    }


    @Override
    public AjaxResult bind(Map<String, String> map) {
        // 获取手机号及验证码
        String phone = map.get("phone");
        String code = map.get("code");

        // 拿到redis中的验证码
        String codeinredis = (String)redisTemplate.opsForValue().get(phone);
        String codereal = codeinredis.split(":")[0];
        // 如果不一致，说明验证码错误
        if(!code.equals(codereal)){
            return AjaxResult.me().setSuccess(false).setMessage("验证码错误");
        }

        // redis中拿openid和access_token，然后去微信拿用户数据
        String openid = (String)redisTemplate.opsForValue().get("openid");
        String access_token = (String)redisTemplate.opsForValue().get("access_token");
        if(openid==null||access_token==null){
            return AjaxResult.me().setSuccess(false).setMessage("已过期，绑定失败");
        }

        //发送请求去微信服务器拿数据
        String res = HttpUtil.sendGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid);
        /*
        {
        "openid":"OPENID",
        "nickname":"NICKNAME",
        "sex":1,
        "province":"PROVINCE",
        "city":"CITY",
        "country":"COUNTRY",
        "headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
        "privilege":[
        "PRIVILEGE1",
        "PRIVILEGE2"
        ],
        "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
        }
         */
        //把结果转换成java对象
        JSONObject jsonObject = JSON.parseObject(res);
        Wxuser wxuser = new Wxuser();
        wxuser.setOpenid(jsonObject.getString("openid"));
        wxuser.setNickname(jsonObject.getString("nickname"));
        wxuser.setSex(jsonObject.getInteger("sex"));
        wxuser.setAddress(jsonObject.getString("country")+jsonObject.getString("province")+jsonObject.getString("city"));
        wxuser.setHeadimgurl(jsonObject.getString("headimgurl"));
        wxuser.setUnionid(jsonObject.getString("unionid"));

        // 根据手机号拿到user对象
        User user = tUserMapper.queryByPhone(phone);
        // 如果手机号不为空，说明之前用手机号注册过，
        if(user!=null){
            //把微信数据传到我们自己数据库中，并与之前的手机号绑定
            wxuser.setUser_id(user.getId());
            tWxuserMapper.save(wxuser);
            // 把登录信息查出来，实现免密登录
            Logininfo logininfo = tLogininfoMapper.queryByUid(user.getId());
            return noPwdLogin(logininfo);
        }else{
            // 这个时候user是一个新用户,要先保存用户拿到id才能绑定
            user.setPhone(phone);
            user.setState(1);
            user.setCreatetime(new Date());
            user.setHeadImg(jsonObject.getString("headimgurl"));
            user.setUsername("u_"+phone);
            tUserMapper.save(user);

            //把微信数据传到我们自己数据库中，并与上面代码才注册的手机号绑定
            wxuser.setUser_id(user.getId());
            tWxuserMapper.save(wxuser);

            //把数据存到logininfo中
            Logininfo logininfo = new Logininfo();
            logininfo.setDisable(1);
            logininfo.setPhone(phone);
            logininfo.setUid(user.getId());
            logininfo.setUsername(user.getUsername());
            tLogininfoMapper.save(logininfo);
            // 实现免密登录
            return noPwdLogin(logininfo);
        }
    }

    private AjaxResult noPwdLogin(Logininfo logininfo) {
        logininfo.setSalt("");
        logininfo.setPassword("");
        String token = UUID.randomUUID().toString();
        // 存入redis中，token，和对象   与之拦截器对比
        redisTemplate.opsForValue().set(token, logininfo, 30, TimeUnit.MINUTES);
        // 将信息发送给前端。前端保存到本地储存中
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("logininfo", logininfo);
        return AjaxResult.me().setResultObj(map);
    }


}
